<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <script>
        // 虚拟dom --  (用js对象来描述一段DOM结构)
        // let app = document.getElementById("app")

        // [1111,  'srrsr', true, {}]  元组

        let oul = {
            tagName: "ul",
            props: {
                id: "app",
                // class: "box",
                class: ["box1","box2"],
                style: {
                    color: "skyblue",
                    background: "green"
                }
            },
            children: [
                {
                   tagName: "li",
                   props: {},
                   children: "1"
                },
                {
                   tagName: "li",
                   props: {},
                   children: "2"
                },
                {
                   tagName: "li",
                   props: {},
                   children: "3"
                }
            ]
        }


        // 遇到一个函数的时候要考虑哪些方面
        // 1. 函数的参数
        // 2. 返回值  --  真实的DOM节点
        // 3. 函数的功能  --  把虚拟DOM节点转换为真实DOM
        // 4. this

        // 封装一个函数，把虚拟DOM节点转换为真实DOM
        function realDom(vNode) {
            // 1. 解构出虚拟DOM上的标签，来生成真实的DOM
            const { tagName, props, children } = vNode
            let rNode = document.createElement(tagName)
            // 2. 给DOM节点添加属性
            // [id, class]
            Object.keys(props).forEach(item => {
                // rNode[item] = props[item]
                // 为了兼容自定义属性，需要改一下写法
                // 兼容一下style的处理
                if (item === "style") {
                    // 通过Object.keys把style中所有属性放入到数组中
                    Object.keys(props[item]).forEach(items => {
                        rNode.style[items] = props[item][items]
                    })
                }else if(item === "class"){
                    props.class.forEach(items => {
                        rNode.classList.add(items);
                    })
                }else {
                    rNode.setAttribute(item, props[item])
                }
            })
            // 3. 把内容添加到节点中
            if (typeof children === "string") {
                // rNode.innerHTML = children
                // 为了兼容标签里有文本还有标签
                // document.createTextNode(创建一个文本节点)
                let oText = document.createTextNode(children)
                // 把文本节点放入到真实节点当中
                rNode.appendChild(oText)
            } else {
                // 递归调用
                children.forEach(item => {
                    rNode.appendChild(realDom(item))
                })
            }
            return rNode
        }

        document.body.appendChild(realDom(oul))
        

        // Object.keys   可以把对象中的key统一放到一个数组中
        // Object.values   可以把对象中的values统一放到一个数组中
        // let obj = {
        //     name: "张三",
        //     age: 18
        // }

        // console.log(Object.values(obj))

    </script>
</body>
</html>